/*****目标团队--靶标 --攻防赛*****/
<template
  ><!---->
  <search-table
    ref="searchTable"
    :columns="targetTeamCol"
    :data="targetAllotList"
    :total="targetAllotTotal"
    :page="queryTargetAllotInfo.pageIndex"
    :size.sync="queryTargetAllotInfo.pageSize"
    @change-size="getTargetSize"
    @change-page="getTargetPage"
  >
    <Alert type="warning" show-icon v-if="step == 'pre' && configMode !== 1" slot="alert">
      <p style="color:#f90">
        注意事项（下发的规则在“路由规则下发记录”中都可以查看到，如果状态为失败，可以重新下发，如果下发内容有误，可以修改下发内容重新下发）:
      </p>
      <p>1.第一步进行“一键题目分配”</p>
      <template v-if="onlineMode == 1">
        <p>2.第二步进行“下发规则”</p>
        <p v-if="targetAllotList.length > 0 && !ctfVpn && ctfOnlineType !== 'ip'">
          3.第三步在“下发规则”完成3分钟后，进行“域名生成”
        </p>
        <p v-if="targetAllotList.length > 0 && !ctfVpn && ctfOnlineType !== 'ip'">4.第四步如果域名没有生效，进行“重启DNS”</p>
      </template>
      <template v-else>
        <p>2.第二步进行“下发规则”</p>
      </template>
    </Alert>
    <template slot="search">
      <Button
        type="primary"
        ghost
        @click="autoAllotTopoTarget(1)"
        v-if="step == 'pre' && configMode !== 1"
        :disabled="disAutoAllot || disabledAllBtn || targetAllotList.length > 0"
        style="margin-right:15px; margin-bottom: 10px;"
      >
        <img
          src="../../../../assets/scene/auto-target-allot-purple.png"
          alt=""
        />一键题目分配</Button
      >
      <Button
        type="error"
        ghost
        icon="md-add"
        @click="autoAllotTopoTargetTip(0)"
        v-if="step == 'pre' && configMode !== 1"
        :disabled="disabledAllBtn"
        style="margin-right:15px; margin-bottom: 10px;"
        >撤销分配</Button
      >
      <Button
        type="primary"
        ghost
        icon="ios-nuclear-outline"
        @click="issuedRules"
        :loading="issuedLoading"
        style="margin-right:15px; margin-bottom: 10px;"
        v-if="step == 'pre' && configMode !== 1"
        :disabled="disabledAllBtn"
        class="mr15"
        >下发规则</Button
      >
      <!-- <Button  type='primary' ghost icon="md-add" @click="autoAllotTopoTargetTip(1)" v-if="step == 'pre' && configMode !== 1" :disabled="disabledAllBtn" style="margin-right:15px; margin-bottom: 10px;">下发基础配置</Button> -->
      <!-- 下发端口转发规则与隐藏题目虽然操作相同，但是步骤不同，所以拆成两个按钮分开放 -->
      <!-- <Button
				type='primary'
				ghost
				icon="md-add"
				@click="hideAllOrPortForward(1)"
				v-if="step == 'pre' && onlineMode == 1 && configMode !== 1"
				:disabled="(disabledAllBtn  || (onlineMode == 1 && targetAllotList.length == 0))"
				style="margin-right:15px; margin-bottom: 10px;">
			<span>下发端口转发规则</span>
		</Button>
		<Button 
			type='primary' 
			v-if="onlineMode == 0 && deployMode === 2 && configMode !== 1" 
			@click="createPublicNetworkRouterRules" 
			:disabled="disabledAllBtn"
			style="margin-right:15px; margin-bottom: 10px;">下发竞赛系统路由规则</Button>
		<Button 
			type='primary' 
			v-if="onlineMode == 1 && configMode !== 1" 
			@click="createPublicNetworkRouterRules" 
			:disabled="disabledAllBtn"
			style="margin-right:15px; margin-bottom: 10px;">下发公网路由规则</Button> -->
      <!-- 隐藏题目虽然与下发端口转发规则操作相同，但是步骤不同，所以拆成两个按钮分开放 -->
      <Button
        type="primary"
        ghost
        icon="md-add"
        @click="hideAllOrPortForward(1)"
        v-if="step == 'pre' && onlineMode == 0 && configMode !== 1"
        style="margin-right:15px; margin-bottom: 10px;"
      >
        <span>隐藏所有题目</span>
      </Button>
      <Button
        type="primary"
        ghost
        icon="md-add"
        @click="openDomainModal"
        v-if="targetAllotList.length > 0 && onlineMode == 1 && configMode !== 1 && !ctfVpn && ctfOnlineType !== 'ip'"
        :disabled="disabledAllBtn"
        style="margin-right:15px; margin-bottom: 10px;"
        >域名生成</Button
      >
      <Button
        type="primary"
        ghost
        icon="ios-play-outline"
        @click="restartDns"
        v-if="targetAllotList.length > 0 && onlineMode == 1 && configMode !== 1 && !ctfVpn && ctfOnlineType !== 'ip'"
        :disabled="disabledAllBtn"
        style="margin-right:15px; margin-bottom: 10px;"
        >重启DNS</Button
      >
      <!--<Button  type='primary'  icon="ios-paper-outline" @click="showModifyPwd">靶标密码修改</Button>-->
      <Select filterable
        v-model="queryTargetAllotInfo.category"
        placeholder="选择类型"
        filterable
        @on-change="getTargetPage(1)"
        style="width:150px;margin-right:15px; margin-bottom: 10px;"
        transfer
        clearable
      >
        <Option
          :value="category.dictname"
          v-for="category in questionTypeList"
          :key="category.dictname"
          :title="category.dictname"
          >{{ category.dictname }}</Option
        >
      </Select>
      <Select filterable
        v-model="queryTargetAllotInfo.finishStatus"
        placeholder="是否完成"
        @on-change="getTargetPage(1)"
        clearable
        style="width:150px;margin-right:15px; margin-bottom: 10px;"
        v-if="step != 'pre'"
      >
        <Option :value="1">是</Option>
        <Option :value="0">否</Option>
      </Select>
      <Select filterable
        v-model="queryTargetAllotInfo.teamName"
        placeholder="请选择团队"
        filterable
        clearable
        @on-change="getTargetPage(1)"
        style="width:150px;margin-right:15px; margin-bottom: 10px;"
      >
        <Option v-for="item in teamOptions" :value="item.name" :key="item.id" :title="item.name">{{
          item.name
        }}</Option>
      </Select>
      <Select filterable
        v-model="queryTargetAllotInfo.questionName"
        placeholder="请选择题目"
        filterable
        @on-change="getTargetPage(1)"
        clearable
        style="width:150px;margin-right:15px; margin-bottom: 10px;"
      >
        <Option
          v-for="item in allTargetTeamData"
          :value="item.name"
          :key="item.id"
          :title="item.name"
          >{{ item.name }}</Option
        >
      </Select>
    </template>
    <!--</div>-->
    <Modal
      v-model="targetModal.show"
      :title="targetModal.title"
      :loading="targetModal.loading"
      width="800px"
      :mask-closable="false"
      @on-cancel="closeTargetModal"
      @on-ok="targetAllot"
    >
      <Form ref="formValidate" :model="formValidate" :rules="ruleValidate" :label-width="100">
        <FormItem label="靶标" prop="targetId">
          <Select filterable
            v-model="formValidate.targetId"
            placeholder="请选择题目"
            @on-change="changeTarget"
            filterable
          >
            <Option
              v-for="target in targetTeamData"
              :value="target.id"
              :key="target.id"
              :title="target.name"
              >{{ target.name }}</Option
            >
          </Select>
        </FormItem>
        <FormItem label="人员设备" prop="idsTOS" v-show="formValidate.targetId">
          <!--{{formValidate.idsTOS}}-->
          <!--<Row>
			<Table size="small" :columns="idsTOSCol" :data="formValidate.idsTOS"></Table>
		</Row>-->
          <!--<Table size="small" :columns="idsTOSCol" :data="formValidate.idsTOS"></Table>-->
        </FormItem>
        <Table
          size="small"
          :columns="idsTOSCol"
          :data="formValidate.idsTOS"
          v-show="formValidate.targetId"
        ></Table>
      </Form>
      <Form ref="addFormValidate" :model="formValidate" :rules="ruleValidate" :label-width="100">
        <Card v-show="formValidate.targetId">
          <FormItem label="团队" prop="teamId">
            <Select filterable
              v-model="formValidate.teamId"
              placeholder="请选择团队"
              @on-change="changeTeamGroup"
            >
              <Option
                v-for="item in teamOptions"
                :value="item.id"
                :key="item.id"
                :title="item.name"
                >{{ item.name }}</Option
              >
            </Select>
          </FormItem>
          <FormItem label="子网络" prop="subnetId">
            <Select filterable
              v-model="formValidate.subnetId"
              placeholder="请选择子网络"
              @on-change="changeSubnet"
            >
              <!--<Option value="all">所有</Option>-->
              <Option
                v-for="item in subnetList"
                :value="item.id"
                :key="item.id"
                :title="item.name"
                >{{ item.name }}</Option
              >
            </Select>
          </FormItem>
          <FormItem label="虚拟机" prop="vmId">
            <Select filterable
              v-model="formValidate.vmId"
              placeholder="请选择虚拟机"
              filterable
              @on-change="changeVm"
            >
              <Option v-for="item in vmlists" :value="item.id" :key="item.id" :title="item.name">{{
                item.name
              }}</Option>
            </Select>
          </FormItem>
          <FormItem label="是否显示" prop="visibility">
            <RadioGroup v-model="formValidate.visibility">
              <Radio :label="1">显示</Radio>
              <Radio :label="0">不显示</Radio>
            </RadioGroup>
            <span style="color:#f90" v-if="type == 4">
              <Icon type="ios-information-circle-outline" />用于在演练页面的展示控制</span
            >
            <span style="color:#f90" v-if="type == 1">
              <Icon type="ios-information-circle-outline" />用于在竞赛页面的展示控制</span
            >
          </FormItem>
          <FormItem label="外网IP" prop="externalIp">
            <Input
              v-model.trim="formValidate.externalIp"
              placeholder="请输入对外IP"
              readonly
              disabled
            ></Input>
          </FormItem>
          <Button type="info" ghost long @click="addIdTOS">添加人员设备</Button>
        </Card>
      </Form>
    </Modal>
    <Modal
      v-model="modifyTargetModal.show"
      :title="modifyTargetModal.title"
      :loading="modifyTargetModal.loading"
      width="600px"
      :mask-closable="false"
      @on-cancel="handleReset('allotFormValidate')"
      @on-ok="modifyTargetAllot"
    >
      <Form
        ref="allotFormValidate"
        :model="allotFormValidate"
        :rules="ruleValidate"
        :label-width="100"
      >
        <FormItem label="靶标" prop="basicTargetId">
          <Select filterable
            v-model="allotFormValidate.basicTargetId"
            placeholder="请选择靶标"
            @on-change="changeTarget"
            filterable
          >
            <Option
              v-for="target in targetTeamData"
              :value="target.id"
              :key="target.id"
              :title="target.name"
              >{{ target.name }}</Option
            >
          </Select>
        </FormItem>
        <FormItem label="团队" prop="teamId">
          <Select filterable v-model="allotFormValidate.teamId" placeholder="请选择团队">
            <Option
              v-for="item in teamOptions"
              :value="item.id"
              :key="item.id"
              :title="item.name"
              >{{ item.name }}</Option
            >
          </Select>
        </FormItem>
        <FormItem label="子网络" prop="subnetId">
          <Select filterable
            v-model="allotFormValidate.subnetId"
            placeholder="请选择子网络"
            @on-change="changeSubnet"
          >
            <!--<Option value="all">所有</Option>-->
            <Option v-for="item in subnetList" :value="item.id" :key="item.id" :title="item.name">{{
              item.name
            }}</Option>
          </Select>
        </FormItem>
        <FormItem label="虚拟机" prop="vmId">
          <Select filterable v-model="allotFormValidate.vmId" placeholder="请选择虚拟机" filterable>
            <Option v-for="item in vmlists" :value="item.id" :key="item.id" :title="item.name">{{
              item.name
            }}</Option>
          </Select>
        </FormItem>
        <FormItem label="是否显示" prop="visibility">
          <RadioGroup v-model="allotFormValidate.visibility">
            <Radio :label="1">显示</Radio>
            <Radio :label="0">不显示</Radio>
          </RadioGroup>
          <span style="color:#f90" v-if="type == 4">
            <Icon type="ios-information-circle-outline" />用于在演练页面的展示控制</span
          >
          <span style="color:#f90" v-if="type == 1">
            <Icon type="ios-information-circle-outline" />用于在竞赛页面的展示控制</span
          >
        </FormItem>
        <FormItem label="外网IP" prop="externalIp">
          <Input v-model.trim="allotFormValidate.externalIp" placeholder="请输入对外IP"></Input>
        </FormItem>
        <!--<FormItem  label="外网服务端口 " prop="externalServicePort" v-if="type == 1">
		<Input v-model.trim="allotFormValidate.externalServicePort" placeholder="请输入PORT(1~65535)"></Input>
		</FormItem>
		<FormItem  label="外网访问端口" prop="externalPort">
		<Input v-model.trim="allotFormValidate.externalPort" placeholder="请输入PORT(1~65535)"></Input>
		</FormItem>-->
      </Form>
    </Modal>
    <modify-pwd ref="modifyPwd"></modify-pwd>
    <Modal v-model="tagsModal" title="提示信息" width="800px" :mask-closable="false" footer-hide>
      <Card v-for="tag in curTarget.targetTagsVOS" :key="tag.tag">
        {{ tag.info }}
        <Button
          @click="changeTagVisible(tag)"
          size="small"
          :type="tag.tagVisibility == 0 ? 'info' : 'error'"
          style="float:right"
        >
          <span v-if="tag.tagVisibility == 0">显示</span>
          <span v-else>隐藏</span>
        </Button>
      </Card>
    </Modal>
    <Modal
      v-model="submitFlagChallModal.show"
      :title="submitFlagChallModal.title"
      :mask-closable="false"
      :loading="submitFlagChallModal.loading"
      @on-ok="toSubmitFlag('challformValidate')"
      @on-cancel="handleReset('challformValidate')"
      width="600px"
    >
      <Form
        ref="challformValidate"
        :model="challformValidate"
        :rules="ruleChalValidate"
        :label-width="120"
      >
        <!--<FormItem label="选择需要提交flag的题目" prop="chaId">
					<Select filterable v-model="challformValidate.chaId" placeholder="选择题目"  filterable>
						<Option v-for="item in challslist" :key="item.name"  :value="item.chaId+'#'+item.name">{{item.name}}</Option>
					</Select>
				</FormItem>-->
        <FormItem label="Flag" prop="flag">
          <Input
            type="textarea"
            v-model.trim="challformValidate.flag"
            placeholder="输入题目Flag"
          ></Input>
        </FormItem>
      </Form>
    </Modal>
    <Modal
      v-model="reportGradeModal.show"
      :title="reportGradeModal.title"
      :mask-closable="false"
      :loading="reportGradeModal.loading"
      @on-ok="reportGrade('gradeValidate')"
      @on-cancel="handleReset('gradeValidate')"
      width="400px"
    >
      <Form ref="gradeValidate" :model="gradeValidate" :rules="ruleChalValidate" :label-width="80">
        <FormItem label="评分" prop="score">
          <InputNumber
            type="textarea"
            v-model="gradeValidate.score"
            :min="1"
            :max="curTarget.ctfScore"
            :placeholder="'输入1~' + tagMaxScore + '的数字'"
            style="width:200px"
          ></InputNumber>
          <p style="color:#ff9900" v-if="hasApplyTag">
            <Icon type="ios-information-circle-outline" />该题已经申请过提示，无法获得满分
          </p>
        </FormItem>
      </Form>
    </Modal>
    <Modal
      v-model="domainModal.show"
      :title="domainModal.title"
      :mask-closable="false"
      :loading="domainModal.loading"
      @on-ok="domainConfig('domainValidate')"
      width="600"
    >
      <Form
        ref="domainValidate"
        :model="domainValidate"
        :rules="ruleDomainValidate"
        :label-width="80"
      >
        <!--<FormItem label="公网子网" prop="publicSubnetId">
		            <Select filterable v-model="domainValidate.publicSubnetId" placeholder="请选择子网" filterable @on-change="getAvailableIP">
		              <Option v-for="item in publicSubnets" :value="item.id" :key="item.id">名称：{{item.name}}CIDR：{{item.cidr}}}</Option>
		            </Select>
		        </FormItem>
		        <FormItem label="外网IP" prop="ip">
		            <Select filterable v-model="domainValidate.ip" placeholder="请选择IP" filterable>
		              <Option v-for="item in availableIPs" :value="item" :key="item">{{item}}</Option>
		            </Select>
		        </FormItem>-->
        <FormItem label="域名" prop="domain">
          <Input
            v-model.trim="domainValidate.domain"
            :placeholder="domainTip"
            :maxlength="20"
          ></Input>
          <!--<p style="color:#ff9900" v-if="hasApplyTag"> <Icon type="ios-information-circle-outline" />该题已经申请过提示，最高得分只能是该题目满分的一半</p>-->
        </FormItem>
      </Form>
    </Modal>
    <Modal
      v-model="loading"
      title="路由下发"
      width="400px"
      :mask-closable="false"
      :closable="false"
      footer-hide
    >
      <h3>
        <Icon
          type="ios-loading"
          size="24"
          class="demo-spin-icon-load"
          style="margin-right:24px;"
        ></Icon
        >{{ distriTip }} <span v-if="minDown > 0">{{ minDown }}</span>
      </h3>
      <Alert type="warning" show-icon style="margin-top:10px;">请勿离开此页面！！</Alert>
    </Modal>
    <Modal v-model="pdfModal" title="pdf预览" width="60" :mask-closable="false" footer-hide>
      <!--<iframe src="http://172.18.100.4:18769/ftp/edu-ftp/viewOnline/pdf/F102b386-f32c-4868-902f-00bc1886145b" width="100%" height="600px" ></iframe>-->
      <iframe :src="pdfUrl" width="100%" height="600px" scrolling="none" frameborder="0"></iframe>
    </Modal>
    <Modal v-model="addOrSubModal" :title="addOrSubModalTitle" @on-visible-change="visibleChange">
      <Alert type="warning" show-icon>
        1. 本操作仅记录最后一次加/减分，如存在多次加/减分的情况，请设置最终加/减分值<br />
        2. 扣分不得大于题目的真实得分
      </Alert>
      <Form ref="addOrSubModal" :model="addOrSubForm" :rules="addOrSubRules" :label-width="56">
        <FormItem :label="addOrSubModalLabel" prop="addScore">
          <Input
            :prefix="addOrSubModalType === 1 ? 'md-add' : 'md-remove'"
            v-model="addOrSubForm.addScore"
            number
            :placeholder="`请输入${addOrSubModalLabel}`"
          />
        </FormItem>
      </Form>
      <div slot="footer">
        <Button @click="addOrSubModal = false">取消</Button>
        <Button @click="confirm" type="primary">确定</Button>
      </div>
    </Modal>
    <Modal
      v-model="flagsModal"
      title="Flag信息"
      width="800px"
      :mask-closable="false"
      @on-ok="updateFlags"
      @on-cancel="flagsModal = false"
      :footer-hide="step === 'pre' ? false : true"
    >
      <ctfFlag ref="ctfFlags" :target="curTarget" v-if="flagsModal" :showScore="false"></ctfFlag>
    </Modal>
  </search-table>
</template>

<script>
import ctfFlag from './ctfFlag.vue'
import {
  queryVmWithParty,
  ctfTargetAllot,
  queryCtfTarget,
  queryCtfTargetAllot,
  changeTagVisible,
  submitFlag,
  reportGrade,
  queryNetworkList,
  dnsConfig,
  restartDns,
  queryPublicSubnets,
  getAvailableIP,
  getExecutionsResult,
  quickCreateProgress,
  batchUpdateTeamFlags,
  hideAllTarget
} from '@/api/drill_compete'
import { getDevicePortsById, addOrSub } from '@/api/drill_compete.js'
import { getDictInfoByName } from '@/api/dict.js'
import { getstatusbyprjid, hxRouterVms, hostDetail, issuedRules } from '@/api/drill'
import { downloadSubmitAllReport } from '@/api/compitionStatic.js'
import { getaccessgrouplist } from '@/api/access_new'
import modifyPwd from './modifyPwd'
import disRouteFun from '@/view/drill_compete/page/targetTeam/mixin'
import { queryVmStatus } from '@/api/remote.js'
import { experType } from '@/api/dict'
import { validateDomain, domainTip } from '@/libs/reg'
export default {
  name: 'scenes',
  props: [
    'type',
    'poll',
    'step',
    'onlineMode',
    'extension',
    'disabledAllBtn',
    'ip',
    'gateway',
    'ctfDeduction',
    'deployMode',
    'drillStatus',
    'isBasicScore',
    'configMode',
    'disabledAllBtn'
  ],
  components: { modifyPwd, ctfFlag },
  mixins: [disRouteFun],
  data() {
    const validateNum = (rule, value, callback) => {
      // 验证数字为整数，范围为0~100
      if ((!value && value !== 0) || !Number.isInteger(value)) {
        callback(new Error('请输入整数'))
      } else {
        let maxScore = this.addOrSubModalType === 1 ? 100 : this.currentScore
        if (value < 0 || value > maxScore) {
          callback(new Error(`请输入0-${maxScore}的整数`))
        }
        callback()
      }
    }
    const validatePort = (rule, value, callback) => {
      //验证只能填入数字
      var reg = new RegExp('^([1-9][0-9]{0,1}|65535)$')
      //验证警戒值
      if (value) {
        if (!reg.test(parseInt(value))) {
          callback(new Error('请输入1-65535的整数'))
        } else {
          callback()
        }
      } else {
        callback()
      }
    }
    const validateIP = (rule, value, callback) => {
      //验证只能填入数字
      var reg = new RegExp(
        '^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$'
      )
      //验证警戒值
      if (value) {
        if (!reg.test(value)) {
          callback(new Error('ip格式错误'))
        } else {
          callback()
        }
      } else {
        callback()
      }
    }
    const validateScore = (rule, value, callback) => {
      let score = this.tagMaxScore // 得分的最高分需要实时计算
      if ((value && (value > score || value < 1)) || value === 0) {
        callback(new Error(`请输入1~${score}的数字`))
      } else {
        callback()
      }
    }
    return {
      domainTip,
      issuedLoading: false,
      questionTypeList: [], // 题目类型
      ctfHiddenConfig: false,
      allTargetTeamData: [],
      publicNetworkRouter: [], // 公网路由或者是竞赛系统路由
      queryRouteInfo: {
        // 查询路由的对象
        page: 1,
        pageSize: 10,
        projectId: this.$route.query.prjid
      },
      routeParams: {
        id: this.$route.query.id,
        prjid: this.$route.query.prjid
      },
      targetModal: {
        show: false,
        title: '',
        loading: true,
        type: 1 //1添加，2修改
      },
      modifyTargetModal: {
        show: false,
        title: '修改分配',
        loading: true
      },
      submitFlagChallModal: {
        show: false,
        title: '提交Flag',
        loading: true
      },
      reportGradeModal: {
        show: false,
        title: '评分',
        loading: true
      },
      domainModal: {
        show: false,
        title: '域名',
        loading: true
      },
      pathList: [],
      accessGroupList: [],
      teamOptions: [],
      vmlists: [],
      allVms: [],
      teamlists: [],
      queryTargetTeamInfo: {
        pageIndex: 1,
        pageSize: 100000,
        sceneId: this.$route.query.id,
        projectId: this.$route.query.prjid
      },
      queryTargetAllotInfo: {
        pageIndex: 1,
        pageSize: 10,
        sceneId: this.$route.query.id
      },
      queryAllTargetAllotInfo: {
        pageIndex: 1,
        pageSize: 2147483647,
        sceneId: this.$route.query.id,
        tag: '1'
      },
      questionList: [],
      access: '1',
      formValidate: {
        idsTOS: [],
        subnetId: '',
        subnetName: '',
        targetId: '',
        vmId: '',
        vmName: '',
        teamId: '',
        teamName: '',
        externalIp: '', //对外ip
        //			  "externalPort": "", //对外端口
        //			  "externalServicePort":"",
        visibility: 0
      },
      allotFormValidate: {
        createTime: '',
        externalIp: '',
        //			  "externalPort": "",
        //			  "externalServicePort": "",
        id: '',
        sceneId: '',
        subnetId: '',
        subnetName: '',
        targetId: '',
        targetName: '',
        teamId: '',
        teamName: '',
        visibility: 0,
        vmId: '',
        vmName: '',
        basicTargetId: ''
      },
      oldFormValidate: {},
      ruleValidate: {
        subnetId: [{ required: true, message: '请选择子网络', trigger: 'change' }],
        questionId: [{ required: true, message: '请选择题目', trigger: 'change' }],
        visibility: [{ required: true, type: 'number', message: '请选择', trigger: 'change' }],
        vmId: [{ required: true, message: '请选择虚拟机', trigger: 'change' }],
        teamId: [{ required: true, message: '请选择团队', trigger: 'change' }],
        targetId: [{ required: true, message: '请选择靶标', trigger: 'change' }],
        basicTargetId: [{ required: true, message: '请选择靶标', trigger: 'change' }],
        idsTOS: [
          { required: true, type: 'array', min: 1, message: '请添加人员设备', trigger: 'change' }
        ],
        //	          externalPort:[
        //	          	{ validator: validatePort, trigger: 'change' }
        //	          ],
        //	          externalServicePort:[
        //	          	{ validator: validatePort, trigger: 'change' }
        //	          ],
        externaIp: [{ validator: validateIP, trigger: 'change' }]
      },
      querytime: {},
      targetTeamCol: [
        //        {
        //          type: 'index',
        //          align: 'center',
        //          ellipsis:true,
        ////          width:60
        //        },
        {
          title: '题目显示名称',
          key: 'questionName',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          placement: 'top-left',
          width: 240
          //          width:100
        },
        {
          title: '环境名称',
          key: 'networkName',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          placement: 'top-left',
          width: 160
        },
        {
          title: '团队名称',
          key: 'teamName',
          align: 'center',
          tooltip: true,
          width: 100
          //	            render:(h, params) => {
          //	              return h('span',this.typeFilter(params.row.type))
          //	            }
        },
        {
          title: '类型',
          key: 'category',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          width: 100
        },
        // {
        //   title:'路径',
        //   key:'url',
        //   align:'center',
        //   tooltip:true,
        //   width:140
        //	            render:(h,params) => {
        //	            	return h('span',params.row.targetTempInfos.filter(t => t.type == 1).length > 0 ? params.row.targetTempInfos.filter(t => t.type == 1)[0].info : '')
        //	            }
        // },
        {
          title: '环境类型',
          key: 'circumstance',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          filter: (circumstance) => (circumstance === 'private' ? '独享环境' : '共享环境'),
          show: () => this.ctfVpn
        },
        {
          title: '是否需要提交Flag',
          key: 'isNeedSubmitFlag',
          align: 'center',
          placement: 'top-right',
          minWidth: 100,
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color:
                    params.row.isNeedSubmitFlag == '1' ? 'var(--status-yes)' : 'var(--status-no)',
                  type: 'border'
                },
                on: {
                  click: () => {
                    //this.showAddAndUpdate(params.row)
                  }
                }
              },
              params.row.isNeedSubmitFlag == '1' ? '是' : '否'
            )
          }
        },
        {
          title: 'Flag',
          key: 'flag',
          tooltip: true,
          minWidth: 80,
          render: (h, params) => {
            let total = params.row.drTargetTeamFlags.length
            return total > 0
              ? h(
                  'a',
                  {
                    on: {
                      click: () => {
                        if (total === 0) {
                          return
                        }
                        //	            				if(params.row.targetTagsVOS.length > 0){
                        this.curTarget = params.row
                        this.flagsModal = true
                        //	            				}
                      }
                    }
                  },
                  'Flag:' + total
                )
              : h('span', '无')
          }
        },
        {
          title: '提示个数',
          key: 'targetTagsVOS',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          placement: 'top-right',
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: 'blue'
                },
                style: {
                  cursor: params.row.targetTagsVOS.length > 0 ? 'pointer !important' : ''
                },
                nativeOn: {
                  click: () => {
                    if (params.row.targetTagsVOS.length > 0) {
                      this.curTarget = params.row
                      this.tagsModal = true
                    }
                  }
                }
              },
              params.row.targetTagsVOS.length
            )
          }
        },
        {
          title: '是否申请提示',
          key: 'targetTags',
          align: 'center',
          placement: 'top-riht',
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: params.row.targetTagsVOS.some((tag) => tag.tagVisibility == 1)
                    ? 'var(--status-yes)'
                    : 'var(--status-no)',
                  type: 'border'
                },
                on: {
                  click: () => {
                    //this.showAddAndUpdate(params.row)
                  }
                }
              },
              params.row.targetTagsVOS.some((tag) => tag.tagVisibility == 1) ? '是' : '否'
            )
          }
        },
        {
          title: '已申请提示个数',
          key: 'seeCount',
          tooltip: true,
          // minWidth: 60,
          show: () => {
            return ['mid', 'end'].includes(this.step)
          }
        },
        {
          title: '是否完成',
          key: 'finishStatus',
          align: 'center',
          placement: 'top-right',
          width: 50,
          show: () => {
            return ['mid', 'end'].includes(this.step)
          },
          render: (h, params) => {
            let text = '否'
            if (params.row.finishStatus == 1) {
              text = '是'
            }
            return h(
              'Tag',
              {
                props: {
                  color: params.row.finishStatus == 1 ? 'var(--status-yes)' : 'var(--status-no)',
                  type: 'border'
                },
                on: {
                  click: () => {
                    //this.showAddAndUpdate(params.row)
                  }
                }
              },
              text
            )
          }
        },
        {
          title: '访问地址',
          key: 'url',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          width: 120
        },
        {
          title: this.ctfOnlineType === 'ip' ? 'IP' : '域名',
          key: 'domainName',
          minWidth: 120,
          tooltip: true,
          show: (data) => {
            return this.onlineMode == 1 && !this.ctfVpn //&& this.ctfOnlineType !== 'ip'
          },
          filter: (domainName) => {
            // let domain = domainName.split(':')
            // return domain.slice(0,domain.length - 1).join(':')
            return domainName.replace(/:\d+/, '') // 去除 :8080 端口号
          }
        },
        {
          title: '端口',
          key: 'port',
          minWidth: 120,
          tooltip: true,
          show: (data) => {
            return this.onlineMode == 1 && !this.ctfVpn //&& this.ctfOnlineType !== 'ip'
          },
          filter: (port, data) => data.domainName.split(':').pop()
        },
        {
          title: '得分',
          key: 'score',
          align: 'center',
          width: 65,
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: 'blue'
                }
              },
              params.row.score
            )
          }
        },
        {
          title: '加/减分',
          key: 'addScore',
          minWidth: 120,
          show: (data) => {
            return !this.isBasicScore
          },
          render: (h, params) => {
            return h(
              'span',
              {
                props: {
                  color: params.row.addScore >= 0 ? 'green' : 'red'
                }
              },
              params.row.addScore
            )
          }
        },
        {
          title: '分值',
          key: 'ctfScore',
          // key:'score',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          width: 60
        },
        // {
        //   title:'创建时间',
        //   key:'createTime',
        //   align:'center',
        //   ellipsis:true,
        //   tooltip:true,
        // },
        {
          title: '完成时间',
          key: 'finishTime',
          // minWidth: 60,
          tooltip: true
        },
        {
          title: '服务状态',
          key: 'serviceStatus',
          tooltip: true,
          // minWidth: 60,
          show: () => {
            return this.step === 'mid'
          },
          render: (h, params) => {
            return h('span', this.handlerServiceStatus(params.row.serviceStatus))
          }
        },
        {
          type: 'showTime',
          title: '报告最后一次提交时间',
          key: 'submitReportTime',
          show: () => {
            return ['mid', 'end'].includes(this.step)
          },
          // minWidth: 60,
          tooltip: true
        },
        {
          title: '操作',
          key: 'action',
          width: 240,
          fixed: 'right',
          show: () => {
            return ['mid', 'end'].includes(this.step)
          },
          opList: [
            {
              txt: '加分',
              show: (data) => {
                return ['mid', 'end'].includes(this.step) && !this.isBasicScore
              },
              disabled: (data) => {
                return data.finishStatus !== 1
              },
              fun: (data) => {
                this.showAddOrSubModal(data, 1)
              }
            },
            {
              txt: '扣分',
              show: (data) => {
                return ['mid', 'end'].includes(this.step) && !this.isBasicScore
              },
              disabled: (data) => {
                return data.finishStatus !== 1
              },
              fun: (data) => {
                this.showAddOrSubModal(data, 0)
              }
            },
            {
              txt: '下载',
              show: (data) => {
                return ['mid', 'end'].includes(this.step)
              },
              disabled: (data) => {
                return !data.fileId
              },
              fun: this.downloadAllReport
            },
            {
              txt: '预览',
              show: (data) => {
                return ['mid', 'end'].includes(this.step)
              },
              disabled: (data) => {
                return !data.fileId
              },
              fun: (data) => {
                window.open(`/api/minio/filePreview?id=${data.fileId}`)
              }
            },
            {
              txt: '提交Flag',
              show: (data) => {
                return ['mid', 'end'].includes(this.step)
              },
              disabled: (data) => {
                return !(data.finishStatus == 0 && data.isNeedSubmitFlag == '1')
              },
              fun: (data) => {
                this.challformValidate.flag = ''
                this.challformValidate.chaId = data.questionId
                this.curTarget = data
                this.submitFlagChallModal.show = true
                this.$refs['challformValidate'].resetFields()
              }
            },
            {
              txt: '评分', //针对题目提交移到了裁判
              show: (data) => {
                return ['mid', 'end'].includes(this.step) && this.extension.wpUpMode == 1
              },
              disabled: (data) => {
                return !data.fileId || data.isNeedSubmitFlag == '1'
              },
              fun: (data) => {
                this.gradeValidate.score = 0
                this.gradeValidate.questionId = data.questionId
                this.gradeValidate.teamId = data.teamId
                this.curTarget = data
                this.reportGradeModal.show = true
              }
            }
          ]
        }
        //	          {
        //	            title:'操作',
        //	            key:'os',
        //	            ellipsis:true,
        //	            width:100,
        //	            render:(h,params)=>{
        //	              return h('div',[
        //	                h('Button',{
        //	                  props:{
        //	                    type:'primary',
        //	                    size:'small'
        //	                  },
        //	                  style:{
        //	                    marginRight:'5px'
        //	                  },
        //	                  on:{
        //	                    click:()=>{
        //this.showAddAndUpdate(params.row)
        //	                      this.modifyTargetModal.show = true;
        //	                      this.allotFormValidate = JSON.parse(JSON.stringify(params.row));
        //	                      this.changeSubnet(this.allotFormValidate.subnetId);
        //	                      this.getAllVmlist().then(data => {
        //	                      	this.allotFormValidate = JSON.parse(JSON.stringify(params.row));
        //	                      	this.changeSubnet(this.allotFormValidate.subnetId);
        //	                      });
        //	                    }
        //	                  }
        //	                },'修改'),
        //	                h('Poptip', {
        //	                  props: {
        //	                    confirm: true,
        //	                    'ok-text': "确定",
        //	                    'cancel-text': "取消",
        //	                    type: 'error',
        //	                    size: 'large',
        //	                    title: '你确定要删除吗?'
        //	                  },
        //	                  on: {
        //	                    'on-ok': () => {
        //	                      this.delTargetTeam(params.row.id)
        //	                    }
        //	                  }
        //	                }, [
        //	                  h('Button', {
        //	                    props: {
        //	                      type: 'error',
        //	                      size: 'small'
        //	                    },
        //	                    style: {
        //	                      marginRight: '5px'
        //	                    },
        //	                  }, '删除')
        //	                ])
        //	              ])
        //	            }
        //	          }
      ],
      idsTOSCol: [
        {
          title: '团队',
          key: 'teamName',
          align: 'center',
          ellipsis: true,
          tooltip: true
        },
        {
          title: '子网络',
          key: 'subnetName',
          align: 'center',
          ellipsis: true,
          tooltip: true
        },
        {
          title: '虚拟机',
          key: 'vmName',
          align: 'center',
          ellipsis: true,
          tooltip: true
        },
        {
          title: '外网IP',
          key: 'externalIp',
          align: 'center',
          ellipsis: true,
          tooltip: true
        },
        //	          {
        //	            title:'外网访问端口',
        //	            key:'externalPort',
        //	            align:'center',
        //	            ellipsis:true,
        //	            tooltip:true,
        //	          },
        //	          {
        //	            title:'外网服务端口',
        //	            key:'externalServicePort',
        //	            align:'center',
        //	            ellipsis:true,
        //	            tooltip:true,
        //	          },
        {
          title: '显示状态',
          key: 'score',
          align: 'center',
          ellipsis: true,
          tooltip: true,
          render: (h, params) => {
            return h(
              'Tag',
              {
                props: {
                  color: params.row.visibility == 1 ? 'success' : 'default',
                  type: 'border'
                },
                on: {
                  click: () => {
                    //this.showAddAndUpdate(params.row)
                  }
                }
              },
              params.row.visibility == 1 ? '是' : '否'
            )
          }
        },
        {
          title: '操作',
          key: 'os',
          ellipsis: true,
          //	            width:200,
          render: (h, params) => {
            return h('div', [
              h(
                'Button',
                {
                  props: {
                    type: 'primary',
                    size: 'small'
                  },
                  style: {
                    marginRight: '5px'
                  },
                  on: {
                    click: () => {
                      let index = this.formValidate.idsTOS.findIndex(
                        (item) => item.id == params.row.id
                      )
                      this.formValidate.idsTOS.splice(index, 1)
                    }
                  }
                },
                '移除'
              )
            ])
          }
        }
      ],
      targetTeamData: [],
      targetTeamTotal: 0,
      TargetId: '',
      projectInfo: {},
      subnetList: [],
      networkId: '',
      teamArr: [],
      networkArr: [],
      vmArr: [],
      idwithName: {},
      targetAllotList: [],
      targetAllotTotal: 0,
      curTarget: {},
      tagsModal: false,
      timeout: {},
      challformValidate: {
        //			  score:0,
        chaId: '',
        flag: ''
      },
      gradeValidate: {
        questionId: '',
        sceneId: this.$route.query.id,
        score: 0,
        teamId: ''
      },
      ruleChalValidate: {
        chaId: [{ required: true, message: '请选择题目', trigger: 'change' }],
        flag: [{ required: true, message: '请输入Flag', trigger: 'change' }],
        score: [
          { required: true, type: 'number', message: '请输入分数', trigger: 'change' },
          { validator: validateScore, trigger: 'change' }
        ]
      },
      configTimeOut: {},
      domain: '',
      domainValidate: {
        domain: ''
        //				publicSubnetId:'',
        //				ip:''
      },
      ruleDomainValidate: {
        domain: [
          { required: true, message: '不能为空', trigger: 'change,blur' },
          { validator: validateDomain, trigger: 'change,blur' }
        ]
        //				publicSubnetId:[
        //					{ required: true, message: '不能为空', trigger: 'change'}
        //				],
        //				ip:[
        //					{ required: true, message: '不能为空', trigger: 'change'}
        //				]
      },
      loading: false,
      distriTip: '',
      minDown: 0,
      pdfUrl: '',
      pdfModal: false,
      allTargetAllotList: [],
      allTargetAllotTotal: 0,
      disAutoAllot: false,
      vmNotRunning: false, // 核心路由并未全部启动
      addOrSubModalType: 0, // 0：扣分  1：加分
      addOrSubModalTitle: '',
      addOrSubModal: false,
      addOrSubForm: {
        addScore: 0, // 减分时传递负分
        id: '' //指定题目ID
      },
      addOrSubRules: {
        addScore: [{ required: true, type: 'number', trigger: 'change', validator: validateNum }]
      },
      environInfo: {},
      //			publicSubnets:[],
      //			availableIPs:[]
      flagsModal: false
    }
  },
  filters: {},
  computed: {
    addOrSubModalLabel() {
      return this.addOrSubModalType === 1 ? '加分' : '扣分'
    },
    showQuestionList() {
      //选出部署了题目镜像虚拟机的题目
      let quesList = []
      this.questionList.forEach((ques) => {
        if (this.allVms.map((vm) => vm.imageName).includes(ques.imageName)) {
          quesList.push(ques)
        }
      })
      return quesList
    },
    hasApplyTag() {
      if (this.curTarget.targetTagsVOS) {
        return this.curTarget.targetTagsVOS.some((tag) => tag.tagVisibility == 1)
      } else {
        return false
      }
    },
    tagMaxScore() {
      //评分最大值
      if (!this.curTarget.ctfScore) {
        return 0
      }
      let score = this.curTarget.ctfScore
      let visibilityList =
        this.curTarget.targetTagsVOS.filter((tag) => tag.tagVisibility == 1) || [] //是否有申请过提示;
      let num = visibilityList.length
      if (num) {
        // 申请了提示，剩余分数需要扣除对应次数的扣分比例
        score = Math.floor(
          this.curTarget.ctfScore - (this.curTarget.ctfScore * this.ctfDeduction * num) / 100
        )
      }
      return score
    },
    ctfVpn() {
      return this.extension ? this.extension.onlineMode === 1 && this.extension.vpn : false
    },
    ctfOnlineType(){
      return this.extension ? this.extension.ctfOnlineType : ''
    },
  },
  beforeDestroy() {
    clearTimeout(this.timeout)
    clearTimeout(this.configTimeOut)
  },
  async mounted() {
    // 这个方法需要放在首位执行，后续方法需要依赖它获取数据
    await quickCreateProgress(this.$route.query.id).then((data) => {
      if (data.code === 1) {
        if (data.data) {
          this.environInfo = JSON.parse(data.data.paramJson)
        }
      }
    })
    this.getQuestionType()
    this.getProjectInfo()
    this.getAccessGroupList()
    //this.getAllVmlist(true);
    this.getTargetTeamList()
    this.getAllTargetTeamList()
    this.queryTargetAllot()
    this.queryAllTargetAllot()
    this.getCtfHiddenConfig()
    if (this.type == 1) {
      //  		this.idsTOSCol.splice(2, 0, {
      //	            title:'服务内网端口',
      //	            key:'externalServicePort',
      //	            align:'center',
      //	            ellipsis:true,
      //	            tooltip:true,
      //	        });
      //	        this.targetTeamCol.splice(7, 0, {
      //	            title:'服务内网端口',
      //	            key:'externalServicePort',
      //	            align:'center',
      //	            ellipsis:true,
      //	            tooltip:true,
      //	        });
    }
    if (this.onlineMode == 1) {
      this.getRouterListByName()
    }
    if (this.deployMode === 2) {
      this.getRouterListByName('竞赛系统')
    }
  },
  methods: {
    updateFlags() {
      let flags = this.$refs['ctfFlags'].formValidate.flagList
      batchUpdateTeamFlags(
        flags.map((flagItem) => {
          let { id, flag } = flagItem
          return { id, flag }
        })
      )
        .then(({ code, data, message }) => {
          if (code === 1) {
            this.$Message.info('修改成功')
            this.queryTargetAllot()
          } else {
            this.$Message.error(message)
          }
        })
        .catch((error) => {
          this.$Message.info('修改失败')
        })
    },

    // 下发团队规则或者竞赛系统路由规则
    issuedRules() {
      this.issuedLoading = true
      issuedRules(this.$route.query.id)
        .then(async ({ code, message }) => {
          if (code !== 1) {
            this.issuedLoading = false
            this.$Message.warning(message)
          } else {
            this.$Message.info('下发规则成功')
            // self->TabPane->Tabs->ctfCompeteDetail，所以需要三个$parent
            this.$parent.$parent.$parent.changePreDefault('routerRules')
          }
        })
        .catch((e) => {
          console.log(e)
          this.issuedLoading = false
          this.$Message.error(`下发规则异常`)
        })
    },
    // 获取题目类型
    getQuestionType() {
      experType('questionType')
        .then(({ code, message, attribute = [] }) => {
          if (code !== 1) {
            this.$Message.warning(message)
          } else {
            this.questionTypeList = ((attribute.attribute[0] || {}).dictEntryList || []).map(
              (item) => {
                return {
                  dictname: unescape(item.dictname)
                }
              }
            )
          }
        })
        .catch(() => {
          this.$Message.error('获取题目类型异常')
        })
    },
    // 确认设置加减分
    confirm() {
      this.$refs.addOrSubModal.validate((validate) => {
        if (validate) {
          this.addOrSubForm.id = this.currentId
          if (this.addOrSubModalType !== 1) {
            // 扣分操作，分数设置需要取反
            this.addOrSubForm.addScore = -this.addOrSubForm.addScore
          }
          addOrSub(this.addOrSubForm)
            .then(({ code, message }) => {
              if (code === 1) {
                this.addOrSubModal = false
                this.$Message.info(`${this.addOrSubModalType ? '加分' : '扣分'}成功`)
                this.queryTargetAllot()
              } else {
                this.$Message.warning(message)
              }
            })
            .catch(() => {
              this.$Message.error(`${this.addOrSubModalType ? '加分' : '扣分'}异常`)
            })
        }
      })
    },
    // 加减分模态框隐藏时重置表单，将所有字段值重置为空并移除校验结果
    visibleChange(type) {
      if (!type) {
        this.$refs.addOrSubModal.resetFields()
      }
    },
    // 显示加减分的模态框
    showAddOrSubModal(obj, type) {
      this.currentId = obj.id // 设置当前准备加减分的监控ID
      this.currentScore = obj.score - obj.addScore
      this.addOrSubModal = true
      this.addOrSubModalType = type
      this.addOrSubModalTitle = obj.questionName
    },
    getCtfHiddenConfig() {
      getDictInfoByName({ name: 'ctfHiddenConfig' }).then(({ code, attribute, message }) => {
        if (code == 1) {
          this.ctfHiddenConfig = attribute.data.value === '1'
        } else {
          if (message === '没查询到数据') {
            // 该数据没有查询到时，并不需要提示错误信息
            this.ctfHiddenConfig = false
            return
          }
          this.ctfHiddenConfig = true
          this.$Message.error(message)
        }
      })
    },
    // 判断核心路由或者竞赛系统路由是否都在运行
    coreRoutingIsRunning(isCompetitionSystem) {
      return new Promise((resolve, reject) => {
        let params = {}
        params.page = 1
        params.pageSize = 2147483647
        params.projectId = this.$route.query.prjid
        params.findPorts = true
        params.sortBy = 'name'
        params.order = 'asc'
        params.vmType = isCompetitionSystem ? 'PRT' : 'DRT'
        // 查询核心路由
        queryVmWithParty(params.projectId, params).then(({ code, data }) => {
          if (code == 1) {
            queryVmStatus(data.list.map((vm) => vm.id))
              .then(({ code, attribute, prompt }) => {
                if (code == 1) {
                  attribute.vms.forEach((item) => {
                    if (
                      !['ACTIVE', 'Running'].includes(
                        item.taskStatus !== 'null' ? item.taskStatus : item.status
                      )
                    ) {
                      this.vmNotRunning = true
                    }
                  })
                  resolve()
                } else {
                  this.$Message.warning(prompt)
                  reject(prompt)
                }
              })
              .catch((error) => {
                reject(`获取${isCompetitionSystem ? '竞赛系统路由' : '核心路由'}开机状态失败!`)
              })
          }
        })
      })
    },
    // 创建公网路由规则
    async createPublicNetworkRouterRules() {
      if (this.publicNetworkRouter.length) {
        // 判断公网路由或者竞赛系统路由是否存在
        let isCompetitionSystem = this.deployMode === 2
        await this.awaitWrap(this.coreRoutingIsRunning(isCompetitionSystem))
        if (this.vmNotRunning) {
          this.$Message.warning(
            `有${isCompetitionSystem ? '竞赛系统路由' : '核心路由'}未开机，请将所有的${
              isCompetitionSystem ? '竞赛系统路由' : '核心路由'
            }启动之后，再下发规则！！！`
          )
          return
        }
        let error,
          rules,
          ip = '192.168.100.11',
          executionIns = [],
          getPortsIsError = false
        for (let i = 0, length = this.publicNetworkRouter.length; i < length; i++) {
          let device = this.publicNetworkRouter[i]
          if (isCompetitionSystem) {
            // 线下赛路由模式
            ;[error, rules] = await this.awaitWrap(
              this.getDictInfoByName('ctfdefaultConfigCompeteSys')
            )
            await getDevicePortsById(device.id)
              .then(({ code, data, message }) => {
                if (code === 0) {
                  this.$Message.warning(message)
                  getPortsIsError = true
                  return
                }
                ip = (data.find((item) => item.enableUsedPublicSubnet === false) || {}).portIps[0]
                  .ipAddress
              })
              .catch(() => {
                this.$Message.error('查询设备端口异常')
                getPortsIsError = true
                return
              })
          } else {
            ;[error, rules] = await this.awaitWrap(this.getDictInfoByName('ctfgwlyConfig-online'))
            if (rules) {
              // 替换外网IP为当前使用的IP
              rules = rules.replace(
                /target1wan_ip\s*=\s*(((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3})/,
                `target1wan_ip=${this.ip}`
              )
              // 替换外网网关
              rules = rules.replace(
                /gateway-address\s*(((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3})/,
                `gateway-address ${this.gateway}`
              )
              // 替换cidr
              rules = rules.replace(
                /wancidr\s*=\s*(((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){2})/,
                `wancidr=${this.ip.slice(0, this.ip.lastIndexOf('/') - 1)}`
              )
            }
            let pwnQuestionList =
              this.allTargetAllotList.filter(
                (item) => item.category.toUpperCase() === 'PWN' && item.url
              ) || []
            if (pwnQuestionList.length) {
              // 有pwn题，公网路由需要插入新的命令行
              let teamIpList = []
              this.teamOptions.forEach((item) => {
                for (let i = 0, length = this.subnetList.length; i < length; i++) {
                  if (item.partyId == this.subnetList[i].party) {
                    teamIpList.push({
                      id: item.id,
                      name: item.name,
                      ip: this.subnetList[i].ip
                    })
                    break
                  }
                }
              })
              let pwnRules = [],
                originIndex = 15
              teamIpList.forEach((item) => {
                pwnQuestionList.forEach((subItem) => {
                  let teamIp = item.ip
                  let [questionIp, port = '80'] = subItem.url.split(':')
                  pwnRules.push(`
                                        target${originIndex}_ip=${teamIp}
                                        target${originIndex}_port=${subItem.port}
                                        target${originIndex}wan_port=${(
                    teamIp.split('.')[3].padStart(2, '0') +
                    questionIp.split('.')[3].padStart(2, '0')
                  ).padStart(5, '5')}
                                        set nat destination rule ${originIndex} description 'Port Forward: $target${originIndex}_ip:$target${originIndex}_port to $target1wan_ip:$target${originIndex}wan_port'
                                        set nat destination rule ${originIndex} inbound-interface $waneth
                                        set nat destination rule ${originIndex} destination address $target1wan_ip
                                        set nat destination rule ${originIndex} destination port $target${originIndex}wan_port
                                        set nat destination rule ${originIndex} source address 0.0.0.0/0
                                        set nat destination rule ${originIndex} protocol tcp
                                        set nat destination rule ${originIndex} translation address $target${originIndex}_ip
                                        set nat destination rule ${originIndex} translation port $target${originIndex}_port
                                    `)
                  originIndex++
                })
              })
              let index = rules.lastIndexOf('commit')
              let per = rules.slice(0, index)
              let next = rules.slice(index)
              rules = `${per}${pwnRules.join('')}${next}`
            }
          }
          // 开始下发规则
          executionIns.push({
            content: this.encode(rules),
            deviceId: device.id,
            enableDelete: false,
            enableWrite: true,
            ip: ip,
            password: device.access[0].password,
            path: '/home/vyos/rule.sh',
            port: device.access[0].port,
            type: device.access[0].accessType,
            username: device.access[0].username
          })
        }
        if (getPortsIsError) {
          return
        }
        if (error) {
          this.$Message.warning(error)
          return
        }
        hxRouterVms(this.$route.query.prjid, executionIns)
          .then((data) => {
            if (data.code == 1) {
              this.$Message.info(`${isCompetitionSystem ? '竞赛系统' : '公网'}规则下发成功`)
            } else {
              this.$Message.warning(data.message)
            }
          })
          .catch(() => {
            this.$Message.error('下发规则异常')
          })
      } else {
        this.$Message.warning('未找到公网路由设备')
      }
    },
    // 获取需要的路由类型列表，默认查询公网路由
    getRouterListByName(name = '公网路由') {
      let params = {}
      params.page = 1
      params.pageSize = 2147483647
      params.projectId = this.$route.query.prjid
      params.findPorts = true
      params.sortBy = 'name'
      params.order = 'asc'
      queryVmWithParty(params.projectId, params)
        .then(({ code, data, message }) => {
          if (code === 1) {
            let { list } = data
            this.publicNetworkRouter = list.filter((item) => item.name === name) || []
          } else {
            this.$Message.error(message)
          }
        })
        .catch(() => {
          this.$Message.error('获取核心路由失败')
        })
    },
    encode(input) {
      var output = ''
      var chr1, chr2, chr3, enc1, enc2, enc3, enc4
      var i = 0
      input = this._utf8_encode(input)

      while (i < input.length) {
        chr1 = input.charCodeAt(i++)
        chr2 = input.charCodeAt(i++)
        chr3 = input.charCodeAt(i++)

        enc1 = chr1 >> 2
        enc2 = ((chr1 & 3) << 4) | (chr2 >> 4)
        enc3 = ((chr2 & 15) << 2) | (chr3 >> 6)
        enc4 = chr3 & 63

        if (isNaN(chr2)) {
          enc3 = enc4 = 64
        } else if (isNaN(chr3)) {
          enc4 = 64
        }

        output =
          output +
          this.keyStr.charAt(enc1) +
          this.keyStr.charAt(enc2) +
          this.keyStr.charAt(enc3) +
          this.keyStr.charAt(enc4)
      }

      return output
    },
    getProjectInfo() {
      getstatusbyprjid(this.$route.query.prjid).then((data) => {
        if (data.code == 1) {
          this.projectInfo = data.attribute
          this.getProjectSubnet()
        }
      })
    },
    getAllTargetTeamList() {
      queryCtfTarget(this.routeParams.id, {
        pageIndex: 1,
        pageSize: 2147483647
      })
        .then((data) => {
          if (data.code == 1) {
            this.allTargetTeamData = data.data.items || data.data
          } else {
            this.$Message.error('获取列表失败')
          }
        })
        .catch((error) => {
          this.$Message.error('获取列表失败')
        })
    },
    getTargetTeamList() {
      queryCtfTarget(this.routeParams.id, this.queryTargetTeamInfo)
        .then((data) => {
          if (data.code == 1) {
            if (data.data.total == 0) {
              this.disAutoAllot = true
            } else {
              this.disAutoAllot = false
            }
          } else {
            this.disAutoAllot = true
            this.$Message.error('获取靶标列表失败')
          }
        })
        .catch((error) => {
          this.disAutoAllot = true
          this.$Message.error('获取靶标列表失败')
        })
    },
    //		getTargetTeamList(){
    //	  		getTargetTeamList_new(this.queryTargetTeamInfo).then(data => {
    //	  			if(data.code==1){
    //	  				this.targetTeamData = data.data.items || data.data;
    //	  				this.targetTeamData.forEach(team => {
    //						this.idwithName[team.id] = {
    //							name:team.name,
    //							id:team.id,
    //							imageName:team.imageName,
    //							imageId:team.imageId,
    //							ip:team.ip
    //						};
    //					})
    //	  				this.targetTeamTotal = data.data.total;
    //	  			}else{
    //
    //	  			}
    //	  		})
    //	  	},
    initData() {
      this.formValidate = {
        idsTOS: [],
        subnetId: '',
        subnetName: '',
        targetId: '',
        externalIp: '', //对外ip
        externalPort: '', //对外端口
        externalServicePort: '',
        visibility: 0
      }
    },
    getAllVmlist() {
      return new Promise((resolve, reject) => {
        let params = {
          page: 1,
          pageSize: 10000,
          sortBy: 'name',
          order: 'asc',
          findPorts: true
        }
        if (this.formValidate.targetId) {
          params.imageId = this.idwithName[this.formValidate.targetId].imageId
        }
        if (this.allotFormValidate.basicTargetId) {
          params.imageId = this.idwithName[this.allotFormValidate.basicTargetId].imageId
        }
        if (this.group) {
          //params.party = this.group.partyId;
        }
        if (this.targetModal.show && this.formValidate.subnetId) {
          params.networkId = this.formValidate.subnetId
        }
        if (this.modifyTargetModal.show && this.allotFormValidate.subnetId) {
          params.networkId = this.allotFormValidate.subnetId
        }
        if (this.modifyTargetAllot.show && this.allotFormValidate.subnetId) {
          params.networkId = this.allotFormValidate.subnetId
        }
        queryVmWithParty(this.routeParams.prjid, params).then((data) => {
          //		    getProjectSevers(params).then(data => {
          if (data.code == 1) {
            this.vmlists = data.data.list || data.data
            this.formValidate.vmId = ''
            this.formValidate.vmName = ''
            if (this.targetModal.show && this.vmlists.length > 0) {
              this.formValidate.vmId = this.vmlists[0].id
              this.formValidate.vmName = this.vmlists[0].name
              //			    		this.queryTargetAllotRelation();
              //	    		this.formValidate.idsTOS = [];
            } else if (this.modifyTargetModal.show && this.vmlists.length > 0) {
              //			    		setTimeout(() => {
              //			    			this.allotFormValidate.vmId = this.vmlists[0].id;
              //			    			this.allotFormValidate.vmName = this.vmlists[0].name;
              //			    		})
            }
            this.vmlists.forEach((vm) => {
              this.idwithName[vm.id] = {
                id: vm.id,
                name: vm.name
              }
            })
            resolve()
            //this.getVmIp(this.formValidate.vmId);
            //					if(this.vmlists.length > 0){
            //						let server = this.vmlists.filter(vm => vm.id == this.formValidate.vmId)[0];
            //	    		        if(server){
            //	    		        	this.formValidate.subnet = server.addresses[0].subnetId;
            //	    		        	this.getFlagServerList(server.address[0].ipv4);
            //	    		        	this.getFlagServerList(server.addresses[0].ip);
            //	    		        }
            //					}
          }
        })
      })
    },
    getAccessGroupList() {
      if (!this.routeParams.id) {
        return
      }
      let params = {
        pageIndex: 1,
        pageSize: 2147483647,
        testId: this.routeParams.id
      }
      this.selectGroupList = []
      getaccessgrouplist(params).then((data) => {
        if (data.code == 1) {
          // 夺旗赛过滤掉spare1组
          let items = data.data.items || []
          this.accessGroupList = items
          this.teamOptions = items.filter((item) => !item.spare)
          //					this.accessGroupList.forEach(group => {
          //						this.idwithName[group.id] = {
          //							id:group.id,
          //							name:group.name
          //						}
          //					})
        } else if (data.code == -2) {
          this.accessGroupList = []
          this.teamOptions = []
        } else {
          this.$Message.warning(data.message)
        }
      })
    },
    showAddAndUpdate(info) {
      this.initData()
      this.targetModal.show = true
      if (!info) {
        this.targetModal.title = '题目分配'
        this.targetModal.type = 1
        this.access = '1'
      } else {
      }
    },
    handleReset(name) {
      this.$refs[name].resetFields()
      this.addTarget = false
      this.initData()
      this.$refs[name].fields.forEach(function(e) {
        if (e.fieldValue != undefined && e.fieldValue != '') {
          e.resetField()
        }
      })
    },
    addTargetTeam() {
      let params = JSON.parse(JSON.stringify(this.formValidate))
      params.questionName = this.question.name
    },
    modifyTargetTeam() {
      let params = JSON.parse(JSON.stringify(this.formValidate))
      params.questionName = this.question.name
    },
    saveTargetTeam() {
      this.$refs['formValidate'].validate((valid) => {
        if (valid) {
          if (this.targetModal.type == 1) {
            this.addTargetTeam()
          } else {
            this.modifyTargetTeam()
          }
        } else {
          this.cancelLoading('targetModal')
        }
      })
    },
    getTargetSize(size) {
      this.queryTargetAllotInfo.pageSize = size
      this.queryTargetAllot()
    },
    getTargetPage(page) {
      this.queryTargetAllotInfo.pageIndex = page
      this.queryTargetAllot()
    },
    changeTeamGroup() {},
    changeTarget(targetId) {
      if (this.targetModal.show) {
        this.formValidate.vmId = ''
        this.formValidate.vmName = ''
        this.formValidate.subnetId = ''
        this.formValidate.subneName = ''
        this.formValidate.teamId = ''
        this.formValidate.teamName = ''
        this.formValidate.externalIp = ''
        this.formValidate.externalPort = ''
        this.formValidate.externalServicePort = ''
        this.queryTargetAllotRelation()
      } else if (this.modifyTargetModal.show) {
        this.allotFormValidate.vmId = ''
        this.allotFormValidate.vmName = ''
      }
      this.getAllVmlist()
    },
    changeSubnet(id) {
      if (!id) {
        return
      }
      //	    	if(this.targetModal.show){
      //	    		this.formValidate.vmId = '';
      //	    		this.formValidate.vmName = '';
      //	    		this.queryTargetAllotRelation();
      ////	    		this.formValidate.idsTOS = [];
      //	    	}else if(this.modifyTargetModal.show){
      //	    		this.allotFormValidate.vmId = '';
      //	    		this.allotFormValidate.vmName = '';
      //	    	}
      if (this.targetModal.show) {
        this.formValidate.externalIp = this.idwithName[this.formValidate.subnetId].ip
      } else if (this.modifyTargetModal.show) {
        this.allotFormValidate.externalIp = this.idwithName[id].ip
      }
      this.getAllVmlist()
    },
    changeVm() {},
    getProjectSubnet() {
      queryNetworkList(this.$route.query.prjid, this.projectInfo.network.id).then((data) => {
        if (data.code == 1) {
          let subnetList = []
          let linkList = []
          data.attribute.editorStage.childs.forEach((item) => {
            subnetList = subnetList.concat(item.childs)
            if (item.links) {
              linkList = linkList.concat(item.links)
            }
          })
          this.subnetList = subnetList.filter((subnet) => subnet.dataType == 'NW')
          this.subnetList.forEach((subnet) => {
            let ip
            if (linkList.filter((link) => link.rightNetId == subnet.id).length > 0) {
              ip = linkList.filter((link) => link.rightNetId == subnet.id)[0].rightIpParts[0]
                .ipAddress
              this.$set(subnet, 'ip', ip)
            }
            this.idwithName[subnet.id] = {
              id: subnet.id,
              name: subnet.name,
              ip: ip
            }
          })
        }
      })
    },
    initAllotForm() {
      this.formValidate.vmId = ''
      this.formValidate.vmName = ''
      this.formValidate.subnetId = ''
      this.formValidate.subneName = ''
      this.formValidate.teamId = ''
      this.formValidate.teamName = ''
      this.formValidate.externalIp = ''
      this.formValidate.externalPort = ''
      this.formValidate.externalServicePort = ''
    },
    addIdTOS() {
      this.$refs['addFormValidate'].validate((valid) => {
        if (valid) {
          //	            	if(this.targetModal.type == 1){
          //	            		this.addTargetTeam();
          //	            	}else{
          //	            		this.modifyTargetTeam();
          //	            	}
          this.formValidate.idsTOS.push({
            vmId: this.idwithName[this.formValidate.vmId].id,
            vmName: this.idwithName[this.formValidate.vmId].name,
            teamId: this.idwithName[this.formValidate.teamId].id,
            teamName: this.idwithName[this.formValidate.teamId].name,
            subnetId: this.formValidate.subnetId,
            subnetName: this.idwithName[this.formValidate.subnetId].name,
            externalIp: this.formValidate.externalIp, //对外ip
            externalPort: this.formValidate.externalPort, //对外端口
            externalServicePort: this.formValidate.externalServicePort,
            visibility: this.formValidate.visibility
          })
          this.initAllotForm()
          //	            }else{
          ////	            	this.cancelLoading('targetModal');
        }
      })
    },
    targetAllot() {
      this.$refs['formValidate'].validate((valid) => {
        if (valid) {
          let params = {
            idsTOS: this.formValidate.idsTOS,
            //					  "subnetId":this.formValidate.subnetId,
            //					  "subnetName":this.idwithName[this.formValidate.subnetId].name,
            targetId: this.formValidate.targetId
          }
          targetAllot(params)
            .then((data) => {
              if (data.code == 1) {
                this.queryTargetAllot()
                this.targetModal.show = false
                this.formValidate.vmId = ''
                this.formValidate.teamId = ''
                this.formValidate.visibility = 0
              } else {
                this.cancelLoading('targetModal')
              }
            })
            .catch((error) => {
              this.cancelLoading('targetModal')
            })
        } else {
          this.cancelLoading('targetModal')
        }
      })
    },
    awaitWrap(promise) {
      return promise.then((data) => [null, data]).catch((err) => [err, null])
    },
    async autoAllotTopoTargetTip(status) {
      if (status == 1) {
        await this.awaitWrap(this.coreRoutingIsRunning())
        if (this.vmNotRunning) {
          this.$Message.warning('有核心路由未开机，请将所有的核心路由启动之后，再下发规则！！！')
          return
        }
        if (this.hxRouterVmList.length == 0) {
          this.$Message.warning('没有核心路由，请查看工程是否部署，核心路由未下发！！！')
          return
        }
        this.allotStatus = 1
        this.loading = true
        this.minDown = 0
        if (this.interval) {
          clearInterval(this.interval)
        }
        let error1, ctfDefaultConfig
        this.distriTip = '准备下发基础配置...'
        if (this.onlineMode == 0) {
          //线下
          if (this.deployMode === 2) {
            // 线下赛路由模式
            ;[error1, ctfDefaultConfig] = await this.awaitWrap(
              this.getDictInfoByName('ctfdefaultConfigForward')
            )
          } else {
            ;[error1, ctfDefaultConfig] = await this.awaitWrap(
              this.getDictInfoByName('ctfdefaultConfig')
            )
          }
        } else {
          //线上
          ;[error1, ctfDefaultConfig] = await this.awaitWrap(
            this.getDictInfoByName('ctfdefaultConfig-online')
          )
        }
        if (error1) {
          this.$Message.error('获取基础配置规则失败!')
          this.loading = false
          return
        }
        let [error2, returnData] = await this.awaitWrap(
          this.getSelHxRouterVms(ctfDefaultConfig, 'ctf路由基础配置')
        )
        if (error2) {
          this.$Message.error('下发基础配置失败!')
          this.loading = false
          return
        }
        if (returnData.code == 1) {
          this.distriTip = '正在下发基础配置...'
          let ids = returnData.data.map((item) => item.id)
          clearTimeout(this.configTimeOut)
          this.deBaseConfig(ids, status) //判断是否执行成功
        } else {
          this.$Message.error('下发基础配置失败!')
          this.loading = false
        }
      } else {
        this.allotStatus = 0
        this.autoAllotTopoTarget(status)
      }
    },
    async deBaseConfig(ids, status) {
      let [error, data] = await this.awaitWrap(this.getExecutionsResult(ids))
      if (error) {
        //this.$Message.error('查询下发状态失败!');
        this.loading = false
        return
      }
      if (data.data.every((item) => item.status == 2)) {
        //执行成功
        this.distriTip = '下发基础配置成功...'
        this.loading = false
        this.$Message.info('下发基础配置成功！！！')
        //				if(this.onlineMode == 0){
        //					await this.awaitHiddenAll();
        //					let [error2,ctfHiddenAll] = await this.awaitWrap(this.getDictInfoByName('allToHidden'));
        //					if(error2){
        //		   				this.$Message.error('获取隐藏所有题目规则失败!');
        //		   				this.loading = false;
        //		   				return;
        //		   			}
        //					let [error3,returnData] = await this.awaitWrap(this.getSelHxRouterVms(ctfHiddenAll,'隐藏ctf所有题目'));
        //					if(error3){
        //						this.$Message.error('下发隐藏所有题目规则失败!');
        //						this.loading = false;
        //						return;
        //					}
        //					this.distriTip = '正在下发隐藏所有题目规则...';
        //					let hideIds = returnData.data.map(item => item.id);
        //					this.deHiddenAll(hideIds,status); //判断是否执行成功
        //				}else{
        //					await this.autoAllotTopoTarget(status);
        //	   				await this.queryTargetAllot();
        //					await this.awaitHiddenAll();
        //					this.autoAllotTopoTargetTipXS(status);
        //				}
      } else if (data.data.some((item) => item.status == 3)) {
        //let data =
        this.$Message.error('下发基础配置失败!')
        this.distriTip = '下发基础配置失败!请检查原因，重新下发！'
        this.loading = false
      } else {
        this.configTimeOut = setTimeout(() => {
          this.deBaseConfig(ids, status)
        }, 2000)
      }
    },
    async hideAllOrPortForward(status) {
      // 隐藏题目不再通过路由规则限制访问，统一后后端开关机来限制用户访问
      this.hideAllTarget()
      return
      await this.awaitWrap(this.coreRoutingIsRunning())
      if (this.vmNotRunning) {
        this.$Message.warning('有核心路由未开机，请将所有的核心路由启动之后，再下发规则！！！')
        return
      }
      this.loading = true
      if (this.onlineMode == 0) {
        //				await this.awaitHiddenAll();
        let [error2, ctfHiddenAll] = await this.awaitWrap(this.getDictInfoByName('allToHidden'))
        if (error2) {
          this.$Message.error('获取隐藏所有题目规则失败!')
          this.loading = false
          return
        }
        if (this.deployMode === 2) {
          // 路由模式需要改写规则，新增四句规则
          let index = ctfHiddenAll.indexOf('set interfaces ethernet')
          if (index !== 0) {
            ctfHiddenAll = `${ctfHiddenAll.substr(0, index)}
							set firewall name $firewall rule 99 action accept
							set firewall name $firewall rule 99 destination address 172.30.100.251/32
							set firewall name $firewall rule 99 protocol tcp
							set firewall name $firewall rule 99 destination port 80
							${ctfHiddenAll.substr(index)}`
          }
        }
        let [error3, returnData] = await this.awaitWrap(
          this.getSelHxRouterVms(ctfHiddenAll, '隐藏ctf所有题目')
        )
        if (error3) {
          this.$Message.error('下发隐藏所有题目规则失败!')
          this.loading = false
          return
        }
        this.distriTip = '正在下发隐藏所有题目规则...'
        let hideIds = returnData.data.map((item) => item.id)
        clearTimeout(this.configTimeOut)
        this.deHiddenAll(hideIds, status) //判断是否执行成功
      } else {
        //				await this.autoAllotTopoTarget(status);
        // 				await this.queryTargetAllot();
        //				await this.awaitHiddenAll();
        this.autoAllotTopoTargetTipXS(status)
      }
    },
    async awaitHiddenAll() {
      return new Promise((resolve) => {
        if (this.onlineMode == 1) {
          this.distriTip = '等待下发端口转发规则...'
        } else {
          this.distriTip = '等待下发隐藏所有题目规则...'
        }
        this.minDown = 60
        this.interval = setInterval(() => {
          if (this.minDown > 0) {
            this.minDown--
          } else {
            clearInterval(this.interval)
            resolve()
          }
        }, 1000)
      })
    },
    async deHiddenAll(ids, status) {
      let [error, data] = await this.awaitWrap(this.getExecutionsResult(ids))
      if (error) {
        //this.$Message.error('查询下发状态失败!');
        this.loading = false
        return
      }
      if (data.data.every((item) => item.status == 2)) {
        //执行成功
        this.distriTip = '下发隐藏所有题目规则成功！！！'
        this.loading = false
        this.$Message.info('下发隐藏所有题目规则成功！！！')
        this.hideAllTarget()
        //	    		this.autoAllotTopoTarget(status);
      } else if (data.data.some((item) => item.status == 3)) {
        //let data =
        this.$Message.error('下发隐藏所有题目规则失败!')
        this.distriTip = '下发隐藏所有题目规则失败!请检查原因，重新下发！'
        this.loading = false
      } else {
        this.configTimeOut = setTimeout(() => {
          this.deHiddenAll(ids, status)
        }, 2000)
      }
    },
    getExecutionsResult(ids) {
      return new Promise((resolve, reject) => {
        getExecutionsResult(ids)
          .then((data) => {
            if (data.code == 1) {
              resolve(data)
            } else {
              this.$Message.error('查询下发状态失败!')
              reject('查询下发状态失败')
            }
          })
          .catch((error) => {
            this.$Message.error('查询下发状态失败!')
            reject('查询下发状态失败')
          })
      })
    },
    //线上模式
    async autoAllotTopoTargetTipXS(status) {
      //	   		await this.autoAllotTopoTarget(status);
      //	   		await this.queryTargetAllot();
      if (status == 0) {
        return
      }
      for (let i = 0; i < this.subnetList.length; i++) {
        let code =
          "#!/bin/vbash\nsource /opt/vyatta/etc/functions/script-template\n configure \n#指定变量 \nwancidr=192.168.20. \nwaneth=`ip a | grep  $wancidr | awk '{print $7}'`\nfirename=local\n"
        let subnet = this.subnetList[i]
        let targetList = []
        this.allTargetAllotList.forEach((target) => {
          if (
            target.url &&
            targetList.filter((item) => item.questionId == target.questionId).length == 0
          ) {
            targetList.push(target)
          }
        })
        for (let j = 0; j < targetList.length; j++) {
          let target = targetList[j]
          let ip = target.url.split(':')[0]
          let servicePort = target.url.split(':')[1]
          let ipLast = Number(ip.split('.').pop())
          //let externalServicePort =4990 + Number(this.idwithName[subnet.id].ip.split('.').pop());
          code += `
	   	  		    target${j + 1}_ip=${ip}
					target${j + 1}_port=${servicePort}
					target${j + 1}wan_ip=${subnet.ip}
					target${j + 1}wan_port=${target.port}
					#配置端口转发
					set nat destination rule ${ipLast - 10} description 'Port Forward: $target${j + 1}_ip:$target${j +
            1}_port to $target${j + 1}wan_ip:$target${j + 1}wan_port'
					set nat destination rule ${ipLast - 10} inbound-interface $waneth
					set nat destination rule ${ipLast - 10} destination address $target${j + 1}wan_ip
					set nat destination rule ${ipLast - 10} destination port $target${j + 1}wan_port
					set nat destination rule ${ipLast - 10} source address 0.0.0.0/0
					set nat destination rule ${ipLast - 10} protocol tcp
					set nat destination rule ${ipLast - 10} translation address $target${j + 1}_ip
					set nat destination rule ${ipLast - 10} translation port $target${j + 1}_port
					#将转发的端口开放
					set firewall name $firename rule ${ipLast + 80} action 'accept'
					set firewall name $firename rule ${ipLast + 80} protocol tcp
					set firewall name $firename rule ${ipLast + 80} destination port $target${j + 1}wan_port
		   	  	`
        }
        code += `
		   	  	  commit
	              save`
        subnet.code = code
      }
      this.getSelHxRouterVmsCtf()
        .then((data) => {
          this.distriTip = '正在下发端口转发规则...'
          let ids = data.data.map((item) => item.id)
          clearTimeout(this.configTimeOut)
          this.dePortForward(ids, status)
        })
        .then((data) => {
          //this.autoAllotTopoTargetTip(status);
        })
    },
    async dePortForward(ids, status) {
      let [error, data] = await this.awaitWrap(this.getExecutionsResult(ids))
      if (error) {
        //this.$Message.error('查询下发状态失败!');
        this.loading = false
        return
      }
      if (data.data.every((item) => item.status == 2)) {
        //执行成功
        this.distriTip = '下发端口转发规则成功！！！'
        this.loading = false
        this.$Message.info('下发端口规则成功!')
        //this.autoAllotTopoTarget(status);
      } else if (data.data.some((item) => item.status == 3)) {
        //let data =
        this.$Message.error('下发端口规则失败!')
        this.distriTip = '下发端口转发规则失败!请检查原因，重新下发！'
        this.loading = false
      } else {
        this.configTimeOut = setTimeout(() => {
          this.dePortForward(ids, status)
        }, 2000)
      }
    },
    //下发核心路由
    getSelHxRouterVmsCtf() {
      return new Promise((resolve, reject) => {
        let projectId = this.$route.query.prjid
        let executionIns = this.hxRouterVmList.map((vm) => {
          let code = this.subnetList.filter((subnet) => subnet.id == vm.networkId)[0].code
          let str = this.encode(code)
          return {
            content: str,
            deviceId: vm.id,
            enableDelete: false,
            enableWrite: true,
            ip: '192.168.100.1',
            password: vm.access[0].password,
            path: '/home/vyos/rule.sh',
            port: vm.access[0].port,
            type: vm.access[0].accessType,
            username: vm.access[0].username,
            description: '线上ctf端口转发'
          }
        })
        hxRouterVms(projectId, executionIns).then((data) => {
          if (data.code == 1) {
            //this.$Message.info('核心路由器下发成功');
            resolve(data)
          } else {
            //this.$Message.error(data.message);
            reject()
          }
        })
      })
    },
    autoAllotTopoTarget(status) {
      return new Promise((resolve, reject) => {
        let params = {
          projectId: this.$route.query.prjid,
          sceneId: this.$route.query.id,
          status: status
        }
        ctfTargetAllot(params)
          .then((data) => {
            if (data.code == 1) {
              this.$Message.info('操作成功')
              // 分配成功后清空搜索条件，回退到首页
              this.queryTargetAllotInfo.pageIndex = 1
              this.queryTargetAllotInfo.category = ''
              this.queryTargetAllotInfo.finishStatus = ''
              this.queryTargetAllotInfo.teamName = ''
              this.queryTargetAllot()
              this.queryAllTargetAllot()
              resolve()
              //调一个新接口 2020-06-22
              //await this.queryTargetAllot();
            } else {
              this.$Message.warning(data.message)
              this.loading = false
            }
          })
          .catch((error) => {
            this.$Message.error(error)
            this.loading = false
          })
      })
    },
    VRIPRelation() {
      let params = this.formValidate.idsTOS.map((item) => {
        return {
          contestId: this.$route.query.id,
          ip: this.idwithName[this.formValidate.targetId].ip,
          targetName: this.idwithName[this.formValidate.targetId].name,
          teamId: item.teamId,
          teamName: item.teamName,
          virtualRouterIP: item.externalIp,
          vmname: item.vmName
        }
      })
      VRIPRelation(params).then((data) => {
        if (data.code == 1) {
        }
      })
    },
    //queryTargetAllot,queryTargetAllotRelation,modifyTargetAllot
    queryTargetAllot() {
      return new Promise((resolve, reject) => {
        if (this.poll) {
          clearTimeout(this.timeout)
        }
        queryCtfTargetAllot(this.queryTargetAllotInfo)
          .then((data) => {
            if (data.code == 1) {
              this.targetAllotList = (data.data.items || []).map((item) => {
                if (item.category.toUpperCase() === 'PWN') {
                  item.domainName = item.domainName.replace(/^http(s)?:\/\//, '')
                  // item.domainName = item.domainName.replace(/\:/, ' ')
                }
                return item
              })
              // console.log(this.targetAllotList)
              this.targetAllotTotal = data.data.total
              if (this.poll) {
                //如果需要轮询
                this.timeout = setTimeout(() => {
                  this.queryTargetAllot()
                }, 5000)
              }
              if (this.step == 'pre') {
                if (this.targetAllotTotal > 0) {
                  this.$emit('setHasTarget', true)
                } else {
                  this.$emit('setHasTarget', false)
                }
              }
              resolve()
            } else {
              this.$Message.warning(data.message)
              if (this.step == 'pre') {
                this.$emit('setHasTarget', false)
              }
            }
          })
          .catch((error) => {
            this.$Message.error(error)
            if (this.step == 'pre') {
              this.$emit('setHasTarget', false)
            }
          })
      })
    },
    queryAllTargetAllot() {
      return new Promise((resolve, reject) => {
        queryCtfTargetAllot(this.queryAllTargetAllotInfo)
          .then((data) => {
            if (data.code == 1) {
              this.allTargetAllotList = data.data.items
              this.allTargetAllotTotal = data.data.total
              resolve()
            } else {
              this.$Message.warning(data.message)
            }
          })
          .catch((error) => {
            this.$Message.error(error)
          })
      })
    },
    queryTargetAllotRelation() {
      let params = {
        pageIndex: 1,
        pageSize: 1000,
        //	   	   	   subnetId:this.formValidate.subnetId,
        basicTargetId: this.formValidate.targetId,
        sceneId: this.$route.query.id
      }
      queryTargetAllotRelation(params)
        .then((data) => {
          if (data.code == 1) {
            this.formValidate.idsTOS = data.data.items
            //	   				if(data.data.items.length > 0){
            //	   					this.formValidate.subnetId = data.data.items[0].subnetId;
            //	   					this.formValidate.subnetName = data.data.items[0].subnetName;
            //	   					this.getAllVmlist();
            //	   				}
          } else {
            this.$Message.warning(data.message)
          }
        })
        .catch((error) => {
          this.$Message.error(error)
        })
    },
    modifyTargetAllot() {
      this.$refs['allotFormValidate'].validate((valid) => {
        if (valid) {
          let params = {
            createTime: this.allotFormValidate.createTime,
            externalIp: this.allotFormValidate.externalIp,
            //					  "externalPort": this.allotFormValidate.externalPort,
            //					  "externalServicePort":this.allotFormValidate.externalServicePort,
            id: this.allotFormValidate.id,
            sceneId: this.allotFormValidate.sceneId,
            subnetId: this.allotFormValidate.subnetId,
            subnetName: this.idwithName[this.allotFormValidate.subnetId].name,
            basicTargetId: this.allotFormValidate.basicTargetId,
            targetName: this.idwithName[this.allotFormValidate.basicTargetId].name,
            teamId: this.allotFormValidate.teamId,
            teamName: this.idwithName[this.allotFormValidate.teamId].name,
            visibility: this.allotFormValidate.visibility,
            vmId: this.allotFormValidate.vmId,
            vmName: this.idwithName[this.allotFormValidate.vmId].name
          }
          modifyTargetAllot(params.id, params)
            .then((data) => {
              if (data.code == 1) {
                this.queryTargetAllot()
                this.modifyTargetModal.show = false
                this.cancelLoading('modifyTargetModal')
                this.$Message.info('操作成功')
              } else {
                this.$Message.warning(data.message)
              }
            })
            .catch((error) => {
              this.$Message.error(error)
              this.cancelLoading('modifyTargetModal')
            })
        } else {
          this.cancelLoading('modifyTargetModal')
        }
      })
    },
    cancelLoading(name) {
      this[name].loading = false
      setTimeout(() => {
        this[name].loading = true
      })
    },
    closeTargetModal() {
      this.handleReset('formValidate')
      this.handleReset('addFormValidate')
    },
    showModifyPwd() {
      this.$refs.modifyPwd.showModel(this.routeParams.id, this.accessGroupList)
    },
    changeTagVisible(item) {
      let status = item.tagVisibility == 0 ? 1 : 0
      changeTagVisible(item.tagsId, status).then((data) => {
        if (data.code == 1) {
          item.tagVisibility = item.tagVisibility == 0 ? 1 : 0
          //	  				this.queryCtfTargetTags();
        } else {
          this.$Message.warning(data.message)
        }
      })
    },
    //提交flag
    toSubmitFlag() {
      let _this = this
      let urlId = ''
      this.$refs.challformValidate
        .validate((valid) => {
          if (valid) {
            let params = {
              id: this.curTarget.id,
              flag: this.challformValidate.flag
            }
            submitFlag(params)
              .then((data) => {
                if (this.extension.touchType !== 2 || this.drillStatus === 3) {
                  // 新盲打模式，或者比赛未结束，不能直接看到提交是否正确
                  if (data.code == 1) {
                    if (data.data.isRight == 1) {
                      _this.$Message.info('Flag验证成功！')
                    } else {
                      _this.$Message.error('Flag验证失败！')
                    }
                    _this.submitFlagChallModal.show = false
                    _this.queryTargetAllot()
                  } else {
                    _this.$Message.warning(data.message)
                    _this.submitFlagChallModal.loading = false
                    setTimeout(() => {
                      _this.submitFlagChallModal.loading = true
                    }, 500)
                  }
                } else {
                  _this.$Message.info('Flag提交成功')
                  _this.submitFlagChallModal.show = false
                }
              })
              .catch((error) => {
                _this.$Message.warning(error)
                _this.submitFlagChallModal.loading = false
                setTimeout(() => {
                  _this.submitFlagChallModal.loading = true
                }, 500)
              })
          } else {
            _this.submitFlagChallModal.loading = false
            setTimeout(() => {
              _this.submitFlagChallModal.loading = true
            }, 500)
            //this.$Message.error('表单输入有误')
          }
        })
        .catch((error) => {
          _this.submitFlagChallModal.loading = false
          setTimeout(() => {
            _this.submitFlagChallModal.loading = true
          }, 500)
        })
    },
    reportGrade() {
      this.$refs.gradeValidate
        .validate((valid) => {
          if (valid) {
            reportGrade(this.gradeValidate)
              .then((data) => {
                if (data.code == 1) {
                  this.reportGradeModal.show = false
                  this.$Message.info('操作成功')
                  this.queryTargetAllot()
                } else {
                  this.reportGradeModal.loading = false
                  setTimeout(() => {
                    this.reportGradeModal.loading = true
                  }, 500)
                  this.$Message.warning(data.message)
                }
              })
              .catch((error) => {
                this.reportGradeModal.loading = false
                setTimeout(() => {
                  this.reportGradeModal.loading = true
                }, 500)
                this.$Message.error(error.response.data.message)
              })
          } else {
            this.reportGradeModal.loading = false
            setTimeout(() => {
              this.reportGradeModal.loading = true
            }, 500)
          }
        })
        .catch(() => {
          this.reportGradeModal.loading = false
          setTimeout(() => {
            this.reportGradeModal.loading = true
          }, 500)
        })
    },
    openDomainModal() {
      this.domainModal.show = true
      this.domainValidate.domain = ''
      this.$refs.domainValidate.resetFields()
      //			this.queryPublicSubnets();
    },
    getVmsDetail(targetList) {
      //获取靶机详情
      let pArr = targetList.map(async (target) => {
        await hostDetail(target.vmId)
          .then((data) => {
            if (data.code == 1) {
              let forwardIp = this.idwithName[data.data.networkId].ip
              let forwardPort = target.port
              this.$set(target, 'forwardIp', forwardIp)
              this.$set(target, 'forwardPort', forwardPort)
            } else {
              this.$Message.error(data.message)
            }
          })
          .catch(() => {
            this.$Message.error('服务异常')
          })
      })
      return pArr
    },
    domainConfig() {
      let projectId = this.$route.query.prjid
      let targetList = []
      this.allTargetAllotList.forEach((target) => {
        //	   	    	&& targetList.filter(item => item.questionId == target.questionId).length == 0
        if (target.url) {
          targetList.push(target)
        }
      })
      Promise.all(this.getVmsDetail(targetList))
        .then((data) => {
          this.$refs.domainValidate.validate((valid) => {
            let data = targetList.map((target) => {
              return {
                forwardIp: target.forwardIp,
                forwardPort: target.forwardPort,
                questionId: target.questionId,
                subjectName: target.questionName,
                teamId: target.teamId,
                teamName: target.teamName,
                questionType: target.category,
                questionIp: target.url.split(':')[0]
              }
            })
            dnsConfig(projectId, this.domainValidate.domain, this.environInfo.outsideIP, data)
              .then((data) => {
                this.domainModal.loading = false
                setTimeout(() => {
                  this.domainModal.loading = true
                }, 500)
                if (data.code == 1) {
                  this.$Message.info('操作成功')
                  this.domainModal.show = false
                  this.queryTargetAllot()
                } else {
                  this.$Message.warning(data.message)
                }
              })
              .catch((error) => {
                this.domainModal.loading = false
                setTimeout(() => {
                  this.domainModal.loading = true
                }, 500)
                this.$Message.error('服务异常')
              })
          })
        })
        .catch(() => {
          this.$Message.error('获取虚拟机详情失败')
        })
    },
    restartDns() {
      let projectId = this.$route.query.prjid
      restartDns(projectId)
        .then((data) => {
          if (data.code == 1) {
            this.$Message.info('操作成功')
          } else {
            this.$Message.warning(data.message)
          }
        })
        .catch((error) => {
          this.$Message.error('服务异常')
        })
    },
    hideAllTarget() {
      return new Promise((resolve, reject) => {
        hideAllTarget(this.$route.query.id)
          .then((data) => {
            if (data.code == 1) {
              this.$Message.info('修改题目显示状态成功')
              this.queryTargetAllot()
              this.queryAllTargetAllot()
            } else {
              this.$Message.error(data.message)
            }
          })
          .catch((error) => {
            this.$Message.error('修改题目显示状态失败')
          })
      })
    },
    handlerServiceStatus(value) {
      const mapStatus = {
        1: '正常',
        2: '异常'
      }
      return mapStatus[value]
    },
    downloadAllReport(data) {
      let sceneId = this.$route.query.id
      let teamName = data.teamName
      downloadSubmitAllReport(sceneId, data.teamName, data.reportIds)
        .then((data) => {
          if (data.type == 'application/octet-stream') {
            const downloadElement = document.createElement('a')
            const href = window.URL.createObjectURL(data)
            downloadElement.href = href
            downloadElement.download = `${teamName}_解题报告.zip`
            document.body.appendChild(downloadElement)
            downloadElement.click()
            document.body.removeChild(downloadElement) // 下载完成移除元素
            window.URL.revokeObjectURL(href) // 释放掉blob对象
          } else {
            this.$Message.error('下载报告失败!不存在文件数据！')
          }
        })
        .catch((error) => {
          this.$Message.error('下载报告失败!')
        })
    }
    //		queryPublicSubnets(){//获取公网子网
    //			queryPublicSubnets().then(data => {
    //				if(data.code == 1){
    //					this.publicSubnets = data.data.list;
    //				}else{
    //					this.publicSubnets = [];
    //				}
    //			}).catch(error => {
    //				this.$Message.error('服务异常');
    //			})
    //		},
    //		getAvailableIP(subnetId){//获取可用IP
    //			getAvailableIP(subnetId,2000).then(data =>{
    //				if(data.code == 1){
    //					this.availableIPs = data.data.ranges;
    //				}else{
    //					this.availableIPs = [];
    //				}
    //			}).catch(error => {
    //				this.$Message.error('服务异常');
    //			})
    //		}
  }
}
</script>

<style>
.drillsTable .ivu-poptip-body {
  text-align: left !important;
}
.scenesHeader {
  margin-bottom: 16px;
}
.drillTables {
  min-height: 300px;
}
.drillsTable.ivu-table-wrapper {
  overflow: inherit;
}
</style>
<style scoped>
.card-list-div {
  margin-top: -10px;
}
.card-list-div >>> #cardList {
  width: 100%;
}
.targetHeader {
  /*padding: 10px;*/
  margin: 15px 0;
}
.demo-spin-icon-load {
  animation: ani-demo-spin 1s linear infinite;
}
@keyframes ani-demo-spin {
  from {
    transform: rotate(0deg);
  }
  50% {
    transform: rotate(180deg);
  }
  to {
    transform: rotate(360deg);
  }
}
</style>
